import os
import uuid

from flask import Blueprint, request, jsonify
from conf.comm import sqlalchemy_context
from database import *
from werkzeug.security import generate_password_hash, check_password_hash
import json
import re
import random
from utils.commins import get_redis_conn, send_message
from utils.redisconn import r

# 蓝图初始化
from views.myjwt import myjwt

bp_users = Blueprint('users', __name__)


# 注册功能实现
@bp_users.route('/reg', methods=['POST'])
@sqlalchemy_context()
def reg():
    if request.method == "POST":
        data = request.data
        if not data:
            data = request.form
        # 获取用户输入
        else:
            data = json.loads(request.data)
        if not re.match('^1[3-9]\d{9}$', data['mobile']):
            return jsonify({"code": 10012})
        else:
            # 有效性验证
            # 构造user
            try:
                user = User(username=data['username'], password=generate_password_hash(data['password']),
                            mobile=data['mobile'])
                db.session.add(user)
                db.session.commit()
                return jsonify({"code": 200})
            except:
                return jsonify({"code": 10010})


@bp_users.route('/sendsms', methods=['POST'])
def sendsms():
    # 传递手机号
    data = json.loads(request.data)
    mobile = data['mobile']
    if not mobile:
        return jsonify({'code': 20010, 'mes': '必须输入手机号'})
    if not re.match('^1[2-9]\d{9}$', mobile):
        return jsonify({"code": 123, "mes": "手机号格式错误"})
    # 用手机号去redis中取验证码，如果能取到返回，请30秒后发
    v = r.get_str(mobile)
    if v:
        return jsonify({"code": 20021, 'mes': '请30秒后发'})
    # 生成验证码
    code = str(random.randint(100000, 999999))
    # 调用短信接口
    flag = send_message(mobile, code, 1)
    if flag:
        # 发送成功，存入redis
        r.set_str(mobile, code, 30)
        # 返回结果（验证码）
        return jsonify({'code': 200, 'smscode': code})
    else:
        return jsonify({'code': 20011, 'mes': '发送失败，请重试'})


@bp_users.route('/mdl', methods=['POST'])
@sqlalchemy_context()
def mdl():
    data = request.data
    if data:
        data = json.loads(request.data)
        mobile = data['mobile']
        if re.match('^1[2-9]\d{9}$', mobile):
            code = data['code']
            if r.get_str(mobile) == str(code):
                user = User.query.filter_by(mobile=mobile).first()
                if not user:
                    users = User(username=mobile, mobile=mobile)
                    db.session.add(users)
                    db.session.commit()
                r.del_str(mobile)
                return jsonify({"code": 200, "mes": "登录成功"})
            else:
                return jsonify({"code": 200, "mes": "验证码错误"})
        else:
            return jsonify({"code": 123, "mes": "手机号格式错误"})
    else:
        return jsonify({"code": 11111, "mes": "不能为空"})


@bp_users.route('/zdl', methods=['POST'])
@sqlalchemy_context()
def zdl():
    data = request.data
    if data:
        data = json.loads(request.data)
        username = data['username']
        password = data['password']
        userdl = User.query.filter_by(username=username).first()
        if userdl:
            if check_password_hash(userdl.password, password):
                return jsonify({"code": 200, "mes": "登录成功"})
            else:
                return jsonify({"code": 1200, "mes": "密码错误"})
        else:

            return jsonify({"code": 1201, "mes": "用户不存在"})


# 中间件 token除了注册和登录 其余都使用
@bp_users.before_request
def before_request():
    if request.path in ('/getuserinfo/'):
        # 获取token
        try:
            token = request.headers['Token']
        except:
            return jsonify({"code": 403, 'mes': '请传递token'})
        # 解密重新对比token
        newtoken = myjwt.jwt_decode(token)
        if newtoken and myjwt.check(token, newtoken):
            # 数据库查询返回
            id = request.args.get('userid')
            User.query.filter_by(id=id).first()
            return 'ok'
        else:
            return jsonify({"code": 403, 'mes': '无权访问'})


# 用户中心
# 返回用户信息接口
@bp_users.route('/getuserinfo/', methods=['GET'])
def getuserinfo():
    userid = request.args.get('userid')
    print(userid)
    user = User.query.filter_by(id=userid).first()
    print(user)
    lst = []
    dic = {}
    dic['id'] = user.id
    dic['username'] = user.username
    dic['mobile'] = user.mobile
    lst.append(dic)
    print(lst)
    return jsonify({'code': 200, 'list': lst})


# 在执行接口前调用
@bp_users.before_request
def before_request():
    # print(request.path)
    # 定义一个白名单，把不需要token认证的接口放到列表里
    list = ['/users/login', '/users/reg', '/users/sendsms']
    if request.path not in list:
        # 获取token
        try:
            token = request.headers['Token']
        except:
            return jsonify({"code": 403, 'mes': '请传递token'})
        # 解密重新对比token
        newtoken = myjwt.jwt_decode(token)
        if newtoken and myjwt.check(token, newtoken):
            pass
        else:
            return jsonify({"code": 403, 'mes': 'token错误'})


# 返回用户信息接口
@bp_users.route('/getuserinfo')
def getuserinfo():
    # 数据库查询返回
    id = request.args.get('userid')
    user = User.query.filter_by(id=id).first()
    dict = {}
    dict['id'] = user.id
    dict['username'] = user.username
    dict['mobile'] = user.mobile
    return jsonify({'code': 200, 'user': dict})


# 头像上传
@bp_users.route('/upload', methods=['POST', 'GET'])
def upload():
    # 获取文件
    file = request.files['file']
    # 上传到upload文件夹
    # 解决文件名被覆盖的问题
    # 1.文件重命名   文件名.后缀
    # 获取文件后缀
    filetext = os.path.splitext(file.filename)[1]
    newfile = uuid.uuid4().hex + filetext
    # 2.在upload下面建立一个文件夹，专业存，文件夹的名字为userid
    userid = request.form.get('userid')
    # 根据userid创建文件夹
    # 判断此用户文件夹是否存在，存在直接写文件，不存在创建
    path = './static/upload/' + str(userid)
    # 不存在创建文件
    if not os.path.exists(path):
        os.mkdir(path)
    file.save(os.path.join(path, newfile))
    return jsonify({"code": 200, 'filename': newfile})


from utils.myfiles import myf


# 获取某用户下所有的文件
@bp_users.route('/getFiles', methods=['GET', 'DELETE'])
def getFiles():
    if request.method == "GET":
        # 获取用户id
        id = request.args.get('userid')
        # 根据用户id调用文件类获取所有文件
        list = myf.show_all(id)
        print(list)
        filelist = []
        for i in list:
            dict = {}
            dict['name'] = i
            dict['url'] = 'http://localhost:5000/static/upload/' + str(id) + "/" + str(i)
            filelist.append(dict)

        return jsonify({"code": 200, 'list': filelist})
    elif request.method == "DELETE":
        # 删除
        # 获取userid，文件名
        userid = request.args.get('userid')
        filename = request.args.get('filename')
        # 调用删除文件方法
        myf.remove_file(userid, filename)
        # 返回结果
        return jsonify({"code": 200})
